
/*
SSD1289 3.2" TFT LCD Image Loader Functions for PIC32MX795F512L
Copyright (C) 2012 Craig Dawson, Aaron Mohtar, Craig Peacock

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

#include <p32xxxx.h>
#include <plib.h>
#include "lcdImage.h"
#include "FSIO.h"

void lcdLoadBitmap(char filename[])
{
    FSFILE * pointer;
    size_t BytesRead;
    BITMAPFILEHEADER bmpheader;
    BITMAPINFOHEADER bmpinfo;

    unsigned int x;
    unsigned int y;
    unsigned int colour;
    unsigned long colour24bit;

    // Read from SDcard
    pointer = FSfopen (filename, "r");

    if (pointer != NULL)
    {
        // Opened file successfully . .
        // Load Bitmap Header
        BytesRead = FSfread(&bmpheader, 1, sizeof(BITMAPFILEHEADER), pointer);
        printf("Magic = %04X\r\n", bmpheader.bfType);
        printf("File Size = %d bytes\r\n", bmpheader.bfSize);
        printf("Offset = %04X\r\n", bmpheader.bfOffset);

        // Load Bitmap Information Header
        BytesRead = FSfread(&bmpinfo, 1, sizeof(BITMAPINFOHEADER), pointer);
        printf("Bitmap Width = %d pixels\r\n", bmpinfo.biWidth);
        printf("Bitmap Height = %d pixels\r\n", bmpinfo.biHeight);
        printf("Bits per pixel = %d\r\n", bmpinfo.biBitCount);
        printf("Compression = %d\r\n", bmpinfo.biCompression);
        printf("Image Size = %d bytes\r\n", bmpinfo.biSizeImage);

        if (bmpinfo.biBitCount == 16)
        {
            // Move to Pixel Image Data
            FSfseek(pointer, bmpheader.bfOffset, SEEK_SET);

            // BMP image data starts from bottom left corner
            for (y = bmpinfo.biHeight; y > 0 ; y--)
            {
                for (x = 0; x < bmpinfo.biWidth; x++)
                {
                        BytesRead = FSfread(&colour, 2, 1, pointer);
                        lcdSetPixel(y - 1, x, colour);
                }
            }
        }
        else if(bmpinfo.biBitCount == 24)
        {
            
            // Move to Pixel Image Data
            FSfseek(pointer, bmpheader.bfOffset, SEEK_SET);

            // BMP image data starts from bottom left corner
            for (y = bmpinfo.biHeight; y > 0 ; y--)
            {
                for (x = 0; x < bmpinfo.biWidth; x++)
                {
                        BytesRead = FSfread(&colour24bit, 3, 1, pointer);
                        colour = ((colour24bit&0xF80000)>>8) | ((colour24bit&0xFC00) >>5) | ((colour24bit&0xF8)>>3); // convert to RGB 565 (16bit)
                        lcdSetPixel(y - 1, x, colour);
                }
            }
                        
                        
            //#define RGB16(red, green, blue) ( ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3))
        }
        else
        {


            printf("Wrong file format\r\n");
        }

        if (FSfclose(pointer) == 0) {
            printf("File Closed Successfully.\r\n");
        } 
    } else {
        switch(FSerror())
        {
            case CE_NOT_INIT:
                printf("Error: Device not initialsed.\r\n");
                break;
            case CE_INVALID_FILENAME:
                printf("Error: Invalid filename.\r\n");
                break;
            case CE_FILE_NOT_FOUND:
                printf("Error: File not found.\r\n");
                break;
            default:
                printf("Error: Unknown error %d.\r\n",FSerror());
                break;
        }
    }
}